package com.example.client.controller;

import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.reactive.function.client.WebClient;

@Controller
@RequiredArgsConstructor
public class OAuth2ClientController {

    private final WebClient webClient;

    @GetMapping("/oauth2/authorization/github")
    public String githubAuth (HttpServletRequest request) {
        return "index";
    }

    @GetMapping("/oauth2/authorization/gitee")
    public String giteebAuth (HttpServletRequest request) {
        return "index";
    }


    @GetMapping("/auth/oauth2/code/github/callback")
    public String github(
            @RequestParam("code") String code,
            @RequestParam(value = "state", required = false) String state) {

        // 处理code和state
        System.out.println("Received code: " + code);
        System.out.println("Received state: " + state);

        // 这里你可以使用code去换取访问令牌
        // 例如调用exchangeForAccessToken(code)

        return "redirect:/index";
    }

    @Value("${spring.security.oauth2.client.registration.gitee.authorization-grant-type}")
    private String grantType;
    @Value("${spring.security.oauth2.client.registration.gitee.client-id}")
    private String clientId;
    @Value("${spring.security.oauth2.client.registration.gitee.client-secret}")
    private String clientSecret;
    @Value("${spring.security.oauth2.client.registration.gitee.redirect-uri}")
    private String redirectUri;
    @Value("${spring.security.oauth2.client.provider.gitee.token-uri}")
    private String tokenEndpoint = "https://gitee.com/oauth/token";

    @GetMapping("/login/oauth2/code/gitee")
    public String gitee(@RequestParam("code") String code,
                        @RequestParam("state") String state,
                        HttpServletRequest request) {

        System.out.println("Received code: " + code);
        System.out.println("Received state: " + state);
        String contextPath = request.getContextPath();
        System.out.println("contextPath: " + contextPath);

        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("grant_type", grantType);
        params.add("code", code);
        params.add("redirect_uri", redirectUri); // 必须与最初请求授权时提供的redirect_uri一致
        params.add("client_id", clientId);
        params.add("client_secret", clientSecret);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);


        // 使用 RestClient 发送 POST 请求
//        var response = restClient.post()
//                .uri("https://gitee.com/oauth/token?grant_type=authorization_code&code=" + code + "&client_id=6c3d8f41b941500911678fa2db22216db19c2089152d1a4dcbfbc431039209b4}&redirect_uri=http://localhost:9001/auth/oauth2/code/gitee/callback&client_secret=f7ba66f884e45e7f21b2eeebf2f5d4311f30d5883def258f587a5e715e4cd3d7")
//                .contentType(APPLICATION_JSON)
////                .body(params)
//                .retrieve()
//                .toBodilessEntity();



//        return webClient.get()
//                .uri("https://127.0.0.1:8090/messages")
//                .attributes(clientRegistrationId("my-oauth2-client"))
//                .retrieve()
//                .toEntityList(Message.class)
//                .block();


        return "redirect:/index";

//        // ResponseEntity<Map> response = restTemplate.postForEntity(tokenEndpoint, request, Map.class);
//        if (response.getStatusCode() == HttpStatus.OK) {
//            Map<String, Object> responseBody = response.getBody();
//            return (String) responseBody.get("access_token");
//        } else {
//            throw new RuntimeException("Failed to obtain access token");
//        }


    }


    // @RegisteredOAuth2AuthorizedClient注解使用，参考 https://docs.springjava.cn/spring-security/reference/servlet/oauth2/client/authorized-clients.html
    // @AuthenticationPrincipal
    @GetMapping("/home")
    public String index(Model model,
                        @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient,
                        @AuthenticationPrincipal OAuth2User oauth2User) {

        // 格式化后的JSON，即显示出带缩进的JSON
//        String jsonPrettyStr = JSONUtil.toJsonPrettyStr(authorizedClient);
//        System.out.println("jsonPrettySt: r" + jsonPrettyStr);
//
//        OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
//        System.out.println("accessToken: " + accessToken);
//        OAuth2RefreshToken refreshToken = authorizedClient.getRefreshToken();
//        System.out.println("refreshToken: " + refreshToken);
//
//        String jsonPretty = JSONUtil.toJsonPrettyStr(oauth2User);
//        System.out.println("jsonPretty: " + jsonPretty);

        model.addAttribute("userName", oauth2User.getName());
        model.addAttribute("clientName", authorizedClient.getClientRegistration().getClientName());
        model.addAttribute("userAttributes", oauth2User.getAttributes());
        return "index";
    }

}
